package com.lipaluma.field.adaptor.impl;

import java.lang.reflect.Field;

import com.lipaluma.annotations.adaptors.Adapt;
import com.lipaluma.annotations.adaptors.standard.Truncate;
import com.lipaluma.context.Context;
import com.lipaluma.field.adaptor.Adaptor;
import com.lipaluma.xml.adaptor.XmlAdaptor;
import com.lipaluma.xml.adaptor.XmlTruncateAdaptor;

/**
 * Adaptor use to truncates the extracted value to a given size. Optionally, a suffix may be added after the truncation. <br>
 * The suffiw will be append only if the truncation is done.
 * <p>
 * To initialize :
 * <ul>
 * 	<li>
 * 	<u><b>By annotations :</b></u> 2 ways are available to initialize the adaptor by annotations.<br/>
 * <ul>
 * <li>By {@link Truncate} annotation.</li>
 * <li>By {@link Adapt} annotation with <code>truncateAt</code> attribute to specify the max size and the optional attribute 
 * <code>suffixWhenTruncate</code> to specify the suffix.</li>
 * </li>
 * </ul>
 * </li>
 * 	<li>
 * 	<u><b>By Xml :</b></u>
 * See the example below to add a truncate adaptor : <br/>
 * <code>
 * &lt;ToMap field="..."   ...><br/>
 * &nbsp;&nbsp;&nbsp;<b>&lt;truncate maxSize="10" suffix="..."/></b><br/>
 * &lt;/ToMap>
 * </code><br/>
 * The <code>maxSize</code> attribute is mandatory and must be an valid integer.
 * </li>
 * </ul>
 * 
 * @author Mario
 */
public class TruncateAdaptor implements Adaptor {

	private int maxSize;
	private String suffix;

	public TruncateAdaptor() {}
	/**
	 * Create a TruncateAdaptor with the given max size
	 * @param maxSize max size of the string value
	 */
	public TruncateAdaptor(int maxSize) {
		this(maxSize, "");
	}
	/**
	 * Create a TruncateAdaptor with the max size and the suffix to append
	 * @param maxSize max size of the string value
	 * @param suffix the suffix to append after the truncation
	 */
	public TruncateAdaptor(int maxSize, String suffix) {
		this.maxSize = maxSize;
		this.suffix = suffix;
	}
	
	@Override
	public boolean init(Context context, Field field) {
		if(field.isAnnotationPresent(Truncate.class)) {
			Truncate annotation = field.getAnnotation(Truncate.class);
			this.maxSize = annotation.at();
			this.suffix = annotation.suffix();
			return true;
		} else if (field.isAnnotationPresent(Adapt.class)) {
			Adapt annotation = field.getAnnotation(Adapt.class);
			if(annotation.truncateAt() > 0) {
				this.maxSize = annotation.truncateAt();
				this.suffix = annotation.suffixWhenTruncate();
				return true;
			}
		}
		return false;
	}
	
	@Override
	public boolean init(Context context, Field field, XmlAdaptor xmlAdaptor) {
		XmlTruncateAdaptor xmlTruncateAdaptor = (XmlTruncateAdaptor) xmlAdaptor;
		this.maxSize = xmlTruncateAdaptor.truncateAt();
		this.suffix = xmlTruncateAdaptor.getSuffix() != null ? xmlTruncateAdaptor.getSuffix() : "";
		return true;
	}
	
	public String adapt(String value) {
		 String result;
		if( value.length() <= maxSize ) {
			result = value;
		} else {
			result = value.substring(0, maxSize) + suffix;
		}
		
		return result;
	}

}
